package com.whz.generic.parameter;

import lombok.Builder;
import lombok.Data;
import lombok.experimental.UtilityClass;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 反射方法参数辅助类:按照参数名称(如 'name')和索引(如 "p0' 为第一个参数,'p1'为第二个参数)反射查询方法的参数值
 *
 * @author whz
 * 2021/8/13
 */
@UtilityClass
public class ParameterDiscoveryUtils {

    private final Map<CacheKey, ParameterDiscoverer> map = new ConcurrentHashMap<>();

    /**
     * 按照参数名称或索引查询参数值
     *
     * @param name   参数名称or索引
     * @param method 方法
     * @param params 参数列表
     * @return 参数值
     */
    public Object lookupVariable(String name, Method method, Object[] params) {
        return getParamNameDiscoverer(method, params).lookupVariable(name);
    }

    private static ParameterDiscoverer getParamNameDiscoverer(final Method method, final Object[] params) {
        CacheKey key = CacheKey.builder().params(params).method(method).build();
        ParameterDiscoverer discoverer = map.get(key);
        if (discoverer == null) {
            discoverer = new ParameterDiscoverer(method, params);
            map.put(key, discoverer);
        }
        return discoverer;
    }

    @Data
    @Builder
    static class CacheKey {
        private Method method;
        private Object[] params;
    }

}
